package com.jjwxc.jwjskandriod.framework.widget;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;

/**
 * 悬浮窗管理器
 */
public class RoundView {
    private ClickListener clickListener = null;

    private static RoundView sFloatingLayer;

    /**
     * 用于控制在屏幕上添加或移除悬浮窗
     */
    private static WindowManager mWindowManager;

    public static boolean isNearLeft = true;  // 判断悬浮球是否在左边

    private static boolean isShow = false;  // 判断悬浮球是否已经显示

    private int mWidth, mHeight;   // 屏幕的宽高

    public static final int WIN_NONE = 0;// 不展示
    public static final int WIN_SMALL = 1;// 小浮标
    public static int winStatus;


    /**
     * 小悬浮窗view的实例
     */
    private RoundWindowSmallView smallWindow;


    /**
     * 大小悬浮窗view的参数
     */
    private static WindowManager.LayoutParams mLayoutParams;


    public static RoundView getInstance() {
        if (null == sFloatingLayer) {
            synchronized (RoundView.class) {
                if (null == sFloatingLayer) {
                    sFloatingLayer = new RoundView();
                }
            }
        }
        return sFloatingLayer;
    }

    /**
     * 显示悬浮窗
     */
    public void showRoundView(Context context, ClickListener listener) {
        if (mWindowManager == null) {
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        }

        // 每一次显示浮窗前都重新获取一次宽高，避免横竖屏切换后宽高变化
        getWidthAndHeight(context);

        if (!isShow) {
            // 处于非显示状态，可以显示
            isShow = true;
            if (winStatus == WIN_NONE) {
                // 处于未创建状态，请创建
                onShow(context);
            } else {
                // 已创建了，直接显示
                if (winStatus == WIN_SMALL) {
                    if (smallWindow != null)
                        smallWindow.setVisibilityState(View.VISIBLE);
                }
            }
        }

        setClickListener(listener);
    }

    /**
     * 隐藏悬浮窗
     */
    public void hideRoundView() {
        if (isShow) {
            // 处于显示状态，可以隐藏
            isShow = false;
            if (winStatus == WIN_SMALL) {
                if (smallWindow != null)
                    smallWindow.setVisibilityState(View.GONE);
            }
        }
    }

    /**
     * 销毁悬浮窗
     */
    public void closeRoundView(Context context) {
        isShow = false;
        winStatus = WIN_NONE;
        removeSmallWindow(context);
    }


    /**
     * 显示小悬浮窗
     *
     * @param context context
     */
    private void onShow(final Context context) {
        new Handler().postDelayed(() -> createSmallWindow(context), 500);
    }

    /**
     * 创建一个小悬浮窗。初始位置在屏幕的左上角位置
     *
     * @param context 必须为应用程序的Context
     */
    public void createSmallWindow(Context context) {
        // 每一次创建前都要重新获取宽高，不然横竖屏切换时会出问题
        getWidthAndHeight(context);
        if (smallWindow == null) {
            smallWindow = new RoundWindowSmallView(context);
            if (mLayoutParams == null) {
                mLayoutParams = new WindowManager.LayoutParams();

                mLayoutParams.format = PixelFormat.RGBA_8888;// 解决带Alpha的32位png图片失真问题
                mLayoutParams.gravity = Gravity.START | Gravity.TOP; // 显示在左上角
                mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
                // 在设置宽高
                mLayoutParams.x = 0;
                mLayoutParams.y = context.getResources().getDisplayMetrics().heightPixels / 3 * 2;

                mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
                mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
            }
        }

        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; // 设置悬浮窗的层次

        if (!isNearLeft) {// 当在屏幕右侧时 重新计算x坐标
            int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            smallWindow.measure(w, h);
            if (Configuration.ORIENTATION_LANDSCAPE == context.getResources().getConfiguration().orientation) {// 横屏
                mLayoutParams.x = mWidth - smallWindow.getMeasuredWidth();
            } else {// 竖屏
                mLayoutParams.x = mWidth - smallWindow.getMeasuredWidth();
            }
        }

        smallWindow.setParams(mLayoutParams);

        // 将悬浮球添加到窗体
        if (smallWindow.getParent() == null) {
            mWindowManager.addView(smallWindow, mLayoutParams);
        }

        winStatus = WIN_SMALL;
    }

    /**
     * 将小悬浮窗从屏幕上移除
     *
     * @param context 必须为应用程序的context
     */
    public void removeSmallWindow(Context context) {
        if (smallWindow != null) {
            if (context != null) {
                if (mWindowManager != null) {
                    try {
                        mWindowManager.removeView(smallWindow);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                smallWindow = null;
            } else {
                smallWindow = null;
            }
        }
    }

    public void setClickListener(ClickListener listener) {
        this.clickListener = listener;
    }

    public void performClick() {
        if (null != clickListener) {
            clickListener.clicked();
        }
    }


    /**
     * 获取全屏状态下的宽高
     */
    public void getWidthAndHeight(Context context) {
        mWidth = context.getResources().getDisplayMetrics().widthPixels;
        mHeight = context.getResources().getDisplayMetrics().heightPixels;

        // 有的手机是有虚拟导航键的，当横屏且全屏时，悬浮球无法靠到最右边，所以要用包含虚拟导航键的屏幕宽度
        Point point = new Point();
        if (mWindowManager != null) {
            mWindowManager.getDefaultDisplay().getRealSize(point);
            mWidth = point.x;
            mHeight = point.y;
        }
    }

    public interface ClickListener {
        public void clicked();
    }
}
